package com.wwj.auction.login.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wwj.auction.common.util.SystemUtil;
import com.wwj.auction.login.entity.OfferRecord;
import com.wwj.auction.login.entity.Shop;
import com.wwj.auction.login.entity.UserAccount;
import com.wwj.auction.login.entity.UserInfo;
import com.wwj.auction.login.entity.to.OfferRecordUserInfoTo;
import com.wwj.auction.login.entity.vo.OfferRecordDetailVo;
import com.wwj.auction.login.entity.vo.OfferRecordVo;
import com.wwj.auction.login.entity.vo.PageModel;
import com.wwj.auction.login.enums.ShopCommitedEnum;
import com.wwj.auction.login.enums.ShopStatusEnum;
import com.wwj.auction.login.mapper.OfferRecordMapper;
import com.wwj.auction.login.mapper.ShopMapper;
import com.wwj.auction.login.mapper.UserAccountMapper;
import com.wwj.auction.login.mapper.UserInfoMapper;
import com.wwj.auction.login.service.OfferRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wwj
 * @since 2021-08-29
 */
@Service
public class OfferRecordServiceImpl extends ServiceImpl<OfferRecordMapper, OfferRecord> implements OfferRecordService {

    @Resource
    private UserAccountMapper userAccountMapper;
    @Resource
    private ShopMapper shopMapper;
    @Resource
    private UserInfoMapper userInfoMapper;

    @Override
    public void saveRecord(OfferRecord offerRecord) {
        // 保存出价记录
        offerRecord.setCreateTime(LocalDateTime.now());
        // 冻结保证金
        UserAccount userAccount = userAccountMapper.selectOne(
                Wrappers.lambdaQuery(UserAccount.class)
                        .eq(UserAccount::getUserId, offerRecord.getUserId()));
        BigDecimal earnestPrice = offerRecord.getEarnestPrice();
        // 从用户账户中扣除保证金的金额
        BigDecimal amount = userAccount.getAmount();
        userAccount.setAmount(amount.subtract(earnestPrice));
        // 加上保证金金额
        userAccount.setFreezeAmount(userAccount.getFreezeAmount().add(earnestPrice));
        // 更新账户余额
        userAccountMapper.updateById(userAccount);
        baseMapper.insert(offerRecord);
    }

    @Override
    public PageModel<OfferRecordVo> listForRecord(Integer userId, Integer page, Integer limit) {
//        Page<OfferRecord> offerRecordPage = new Page<>(page, limit);
        LambdaQueryWrapper<OfferRecord> wrapper = Wrappers.lambdaQuery(OfferRecord.class);
        // 按id降序
        wrapper.orderByDesc(OfferRecord::getId);
        // 根据用户id查询出价记录
        wrapper.eq(OfferRecord::getUserId, userId);
//        List<OfferRecord> offerRecordList = baseMapper.selectPage(offerRecordPage, wrapper).getRecords();
        List<OfferRecord> offerRecordList = baseMapper.selectList(wrapper);
        // 使用一个List存储商品id
        List<Integer> idList = new ArrayList<>();
        List<OfferRecordVo> offerRecordVoList = new ArrayList<>();

        // 遍历数据
        for (OfferRecord offerRecord : offerRecordList) {
            // 获取商品id
            Integer shopId = offerRecord.getShopId();
            // 判断当前商品是否已经被记录
            if (!idList.contains(shopId)) {
                // 将id加入集合
                idList.add(shopId);
                // 若未被记录，则进行数据封装
                OfferRecordVo offerRecordVo = new OfferRecordVo();
                // 设置id
                offerRecordVo.setId(shopId);
                // 根据商品id查询商品信息
                Shop shop = shopMapper.selectById(shopId);
                offerRecordVo.setShopName(shop.getShopName());
                // 记录初始出价次数为1
                offerRecordVo.setOfferCount(1);
                // 设置商品状态
                offerRecordVo.setShopStatus(shop.getStatus());
                Integer shopStatus = shop.getStatus();
                // TODO 若商品状态为已成交，则设置成交状态
                // TODO 若当前商品已超过拍卖的结束时间，则设置成交状态为已撤拍
                if (shopStatus.equals(ShopStatusEnum.COMMITED.getStatus())) {
                    // 需要查询当前商品的最终成交买家，若为当前用户，则成交状态为成功，否则成交状态为失败
                    UserInfo userInfo = this.findBuyer(shopId);
                    // 判断最终成交的买家是否为当前用户
                    if (userId.equals(userInfo.getId())) {
                        // 若为当前用户，则成交状态设置为成功
                        offerRecordVo.setCommitStatus(ShopCommitedEnum.SHOP_SUCCESS.getStatus());
                    } else {
                        // 否则成交状态为失败
                        offerRecordVo.setCommitStatus(ShopCommitedEnum.SHOP_FAIL.getStatus());
                    }
                } else if (shopStatus.equals(ShopStatusEnum.SELLING.getStatus())) {
                    // 若商品状态为拍卖中，则设置成交状态为交易中
                    offerRecordVo.setCommitStatus(ShopCommitedEnum.SHOP_SELLING.getStatus());
                } else {
                    // 商品的其它状态均为交易失败
                    offerRecordVo.setCommitStatus(ShopCommitedEnum.SHOP_FAIL.getStatus());
                }
                // 加入集合
                offerRecordVoList.add(offerRecordVo);
            } else {
                // 若出价的商品已被记录，则只需修改出价次数即可
                for (OfferRecordVo offerRecordVo : offerRecordVoList) {
                    if (offerRecordVo.getId().equals(shopId)) {
                        // 修改出价次数
                        offerRecordVo.setOfferCount(offerRecordVo.getOfferCount() + 1);
                        break;
                    }
                }
            }
        }

        // 封装最终数据
        PageModel<OfferRecordVo> pageModel = new PageModel<>();
        pageModel.setList(offerRecordVoList);
        pageModel.setTotal((long) offerRecordVoList.size());
        return pageModel;
    }

    @Override
    public List<OfferRecordDetailVo> listById(Integer userId, Integer shopId) {
        // 根据用户id和商品id查询对应的出价记录
        List<OfferRecord> offerRecordList = baseMapper.selectList(
                Wrappers.lambdaQuery(OfferRecord.class)
                        .eq(OfferRecord::getUserId, userId)
                        .eq(OfferRecord::getShopId, shopId)
                        .orderByDesc(OfferRecord::getId));
        // 封装Vo数据
        List<OfferRecordDetailVo> offerRecordDetailVoList = offerRecordList.stream().map(offerRecord -> {
            OfferRecordDetailVo offerRecordDetailVo = new OfferRecordDetailVo();
            LocalDateTime createTime = offerRecord.getCreateTime();
            offerRecordDetailVo.setCreateTime(SystemUtil.parseDate(createTime));
            // 查询商品名
            Shop shop = shopMapper.selectById(shopId);
            offerRecordDetailVo.setShopName(shop.getShopName());
            offerRecordDetailVo.setPrice(offerRecord.getOfferPrice().toString());
            offerRecordDetailVo.setMemo("暂无");
            return offerRecordDetailVo;
        }).collect(Collectors.toList());
        return offerRecordDetailVoList;
    }

    @Override
    public OfferRecordUserInfoTo first(Integer shopId) {
        // 通过商品id查询出价记录
        List<OfferRecord> offerRecordList = baseMapper.selectList(
                Wrappers.lambdaQuery(OfferRecord.class)
                        .eq(OfferRecord::getShopId, shopId)
                        // 按照出价降序
                        .orderByDesc(OfferRecord::getOfferPrice));
        if (offerRecordList == null || offerRecordList.size() <= 0) {
            return new OfferRecordUserInfoTo();
        }
        // 第一条记录即为当前商品的最高出价记录
        OfferRecord offerRecord = offerRecordList.get(0);
        // 得到userId
        Integer userId = offerRecord.getUserId();
        // 查询买家信息
        UserInfo userInfo = userInfoMapper.selectById(userId);
        // 获取新的出价
        BigDecimal offerPrice = offerRecord.getOfferPrice();
        OfferRecordUserInfoTo offerRecordUserInfoTo = new OfferRecordUserInfoTo();
        BeanUtils.copyProperties(userInfo, offerRecordUserInfoTo);
        offerRecordUserInfoTo.setOfferPrice(offerPrice);
        return offerRecordUserInfoTo;
    }

    @Override
    public UserInfo findBuyer(Integer shopId) {
        // 通过商品id查询出价记录
        List<OfferRecord> offerRecordList = baseMapper.selectList(
                Wrappers.lambdaQuery(OfferRecord.class)
                        .eq(OfferRecord::getShopId, shopId)
                        // 按照出价降序
                        .orderByDesc(OfferRecord::getOfferPrice));
        if (offerRecordList == null || offerRecordList.size() == 0) {
            // 若集合为空，则说明没有出价记录
            return null;
        } else {
            // 若不为空，则集合的第一个元素即为出价最高的用户
            OfferRecord offerRecord = offerRecordList.get(0);
            Integer userId = offerRecord.getUserId();
            // 通过用户id查询用户信息
            UserInfo userInfo = userInfoMapper.selectById(userId);
            return userInfo;
        }
    }
}
